<?php


namespace App\Elastic;


use Elasticsearch\Client;

abstract class EsModel
{

    /**
     * @var Client $client
     */
    protected $client;

    public function __construct()
    {
        $this->client = ioc('ES');
    }

    abstract public static function getMapping(): array;

    public static function getSetting() {

    }

    abstract public static function getIndex(): string;

    abstract public static function getAlias(): string;

    abstract public static function rebuild();

    abstract public function pushToIndex($mixed);


    public function migrate()
    {
        $aliasName = static::getAlias();
        if (!$this->client->indices()->exists(['index' => $aliasName])) {
            echo "create index" . PHP_EOL;
            $this->createIndex();
            return true;
        }
        try {
            $this->updateIndex();
        } catch (\Exception $e) {
            echo "recreate index" . PHP_EOL;
            $this->reCreateIndex();
        }
        echo "migrate success" . PHP_EOL;
    }

    public function createIndex()
    {
        $this->client->indices()->create([
            'index' => static::getIndex(),
            'body' => [
                'settings' => static::getSetting(),
                'mappings' => [
                    '_doc' => [
                        'properties' => static::getMapping()
                    ]
                ],
                'aliases' => [
                    static::getAlias() => new \stdClass()
                ]
            ]
        ]);
    }

    public function updateIndex()
    {
        $aliasName = static::getAlias();
        $this->client->indices()->close(['index' => $aliasName]);

        $this->client->indices()->putSettings([
            'index' => $aliasName,
            'settings' => static::getSetting()
        ]);

        $this->client->indices()->putMapping([
            'index' => $aliasName,
            'mappings' => [
                '_doc' => [
                    'properties' => static::getMapping()
                ]
            ]
        ]);
        $this->client->indices()->open(['index' => $aliasName]);
    }

    public function reCreateIndex()
    {
        $aliasName = static::getAlias();
        $indexInfo = $this->client->indices()->getAliases(['index' => $aliasName]);

        $indexName = array_keys($indexInfo)[0];
        $newIndex = static::getIndex();
        $this->client->indices()->create([
            'index' => $newIndex,
            'body' => [
                'settings' => static::getSetting(),
                'mappings' => [
                    '_doc' => [
                        'properties' => static::getMapping()
                    ]
                ]
            ]
        ]);
        static::rebuild();
        $this->client->indices()->putAlias(['index' => $newIndex, 'name' => $aliasName]);
        $this->client->indices()->delete(['index' => $indexName]);
    }


}